package cn.eonshine.cuba.inf.modular.logs.service.impl;

import java.util.Calendar;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;

import cn.eonshine.cuba.inf.common.util.DateUtils;
import cn.eonshine.cuba.inf.modular.log.entity.Log;
import cn.eonshine.cuba.inf.modular.log.entity.LogDetail;
import cn.eonshine.cuba.inf.modular.log.service.ILogDetailService;
import cn.eonshine.cuba.inf.modular.log.service.ILogService;
import cn.eonshine.cuba.inf.modular.logs.service.IInfLogCleanService;
import cn.eonshine.cuba.lsms.modular.basic.entity.SysLog;
import cn.eonshine.cuba.lsms.modular.basic.service.SysLogService;
import cn.eonshine.cuba.securitibackup.service.SecurityLogDetailService;
import cn.eonshine.cuba.securitibackup.service.SecurityLogService;
import cn.eonshine.cuba.securitibackup.service.SecuritySysLogService;
import cn.eonshine.cuba.securitybackup.modular.log.entity.SecurityLog;
import cn.eonshine.cuba.securitybackup.modular.log.entity.SecurityLogDetail;
import cn.eonshine.cuba.securitybackup.modular.log.entity.SecuritySysLog;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;

@Service
public class InfLogCleanServiceImpl implements IInfLogCleanService {

	// INF_LOG  INF_LOG_DETAIL
	@Autowired
	private ILogDetailService logDetailService;
	@Autowired
	private ILogService logService;
	@Autowired
	private SecurityLogService securityLogService;
	@Autowired
	private SecurityLogDetailService securityLogDetailService;
	
	// SYS_LOG
	@Autowired
	private SysLogService sysLogService;
	@Autowired
	private SecuritySysLogService securitySysLogService;
	
	@Value("${clean.log-keep-days:7}")
	private Integer keeyDays;
	
	@Override
	public void cleanLog() {
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.DATE, this.keeyDays*-1);
		cal = DateUtils.truncate(cal, Calendar.DATE);
		
		cleanInfLog(cal);
		cleanSISTLOG(cal);
	}
	
	/**
	 * clean SISTLOG system sys_log table records
	 * @param cal
	 */
	private void cleanSISTLOG(Calendar cal) {
		long currentPage = 1l;
		IPage<SysLog> page = sysLogService.getCleanLog(currentPage, DateUtils.getCubaDate(cal.getTime()));
		if(CollectionUtil.isEmpty(page.getRecords())) {
			return;
		}
		List<SecuritySysLog> list = Lists.newArrayList();
		List<String> idList = Lists.newArrayList();
		do {
			List<SysLog> logs = page.getRecords();
			if(CollectionUtil.isEmpty(logs)) {
				break;
			}
			for (SysLog sysLog : logs) {
				SecuritySysLog bean = new SecuritySysLog();
				BeanUtil.copyProperties(sysLog, bean);
				list.add(bean);
				idList.add(sysLog.getId());
			}
			securitySysLogService.saveOrUpdateBatch(list);
			sysLogService.removeByIds(idList);
			list.clear();
			idList.clear();
			page = sysLogService.getCleanLog(currentPage, DateUtils.getCubaDate(cal.getTime()));
		}while(currentPage<=page.getPages());
	}
	
	/**
	 * Clean Interface log
	 * @param cal Calendar date
	 */
	private void cleanInfLog(Calendar cal) {
		long currentPage = 1l;
		IPage<Log> logPages = getLogs(currentPage, cal);
		
		List<LogDetail> allDetailList = Lists.newArrayList();

		List<SecurityLog> entityList = Lists.newArrayList();
		List<String> delIds = Lists.newArrayList();
		
		List<SecurityLogDetail> allSecurityDetailList = Lists.newArrayList();
		List<String> delDetailIds = Lists.newArrayList();
		
		do {
			List<Log> logs = logPages.getRecords();
			if(CollectionUtil.isEmpty(logs)) {
				break;
			}
			if(logs.size()>500) {
				List<List<Log>> parts = Lists.partition(logs, 500);
				for (List<Log> list : parts) {
					List<LogDetail> detailList = logDetailService.selectCleanLogDetails(list);
					allDetailList.addAll(detailList);
				}
			}else {
				allDetailList = logDetailService.selectCleanLogDetails(logs);
			}
			
			// 主表数据
			for(Log log: logs) {
				SecurityLog entity = new SecurityLog();
				BeanUtil.copyProperties(log, entity);
				delIds.add(log.getId());
				entityList.add(entity);
			}
			// 子表数据
			for (LogDetail detail : allDetailList) {
				SecurityLogDetail entity = new SecurityLogDetail();
				BeanUtil.copyProperties(detail, entity);
				delDetailIds.add(detail.getId());
				allSecurityDetailList.add(entity);
			}
			
			securityLogService.saveOrUpdateBatch(entityList);
			securityLogDetailService.saveOrUpdateBatch(allSecurityDetailList);
			entityList.clear();
			allDetailList.clear();
			allSecurityDetailList.clear();
			
			logDetailService.removeByIds(delDetailIds);
			logService.removeByIds(delIds);
			delDetailIds.clear();
			delIds.clear();
			
			logPages = getLogs(currentPage, cal);
			if(CollectionUtil.isEmpty(logPages.getRecords())) {
				break;
			}
		}while(currentPage<=logPages.getPages());
	}
	
	private IPage<Log> getLogs(long currentPageNo, Calendar cal){
		Page<Log> page = new Page<Log>(currentPageNo, 2000);
		page.setAsc("operate_time");
		return logService.selectCleanLogList(page, DateUtils.getCubaDate(cal.getTime()));
	}

}
